package cn.iocoder.yudao.module.base.controller.admin.productwarehouse;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
import cn.iocoder.yudao.module.base.dal.dataobject.productinfo.ProductInfoDO;
import cn.iocoder.yudao.module.base.dal.dataobject.unit.UnitDO;
import cn.iocoder.yudao.module.base.service.productinfo.ProductInfoService;
import cn.iocoder.yudao.module.base.service.unit.UnitService;
import cn.iocoder.yudao.module.wms.api.warehouse.WarehouseApi;
import cn.iocoder.yudao.module.wms.api.warehouse.dto.PositionRespDTO;
import cn.iocoder.yudao.module.wms.api.warehouse.dto.WarehouseRespDTO;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import org.springframework.security.access.prepost.PreAuthorize;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Operation;

import java.util.*;
import java.io.IOException;

import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;

import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;

import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.*;

import cn.iocoder.yudao.module.base.controller.admin.productwarehouse.vo.*;
import cn.iocoder.yudao.module.base.dal.dataobject.productwarehouse.ProductWarehouseDO;
import cn.iocoder.yudao.module.base.service.productwarehouse.ProductWarehouseService;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;

@Tag(name = "管理后台 - 产品仓储信息")
@RestController
@RequestMapping("/base/product-warehouse")
@Validated
public class ProductWarehouseController {

    @Resource
    private ProductWarehouseService productWarehouseService;
    @Resource
    private ProductInfoService productInfoService;
    @Resource
    private UnitService unitService;
    @Resource
    private WarehouseApi warehouseApi;

    @PostMapping("/create")
    @Operation(summary = "创建产品仓储信息")
    @PreAuthorize("@ss.hasPermission('base:product-warehouse:create')")
    public CommonResult<Long> createProductWarehouse(@Valid @RequestBody ProductWarehouseSaveReqVO createReqVO) {
        return success(productWarehouseService.createProductWarehouse(createReqVO));
    }

    @PutMapping("/update")
    @Operation(summary = "更新产品仓储信息")
    @PreAuthorize("@ss.hasPermission('base:product-warehouse:update')")
    public CommonResult<Boolean> updateProductWarehouse(@Valid @RequestBody ProductWarehouseSaveReqVO updateReqVO) {
        productWarehouseService.updateProductWarehouse(updateReqVO);
        return success(true);
    }

    @DeleteMapping("/delete")
    @Operation(summary = "删除产品仓储信息")
    @Parameter(name = "id", description = "编号", required = true)
    @PreAuthorize("@ss.hasPermission('base:product-warehouse:delete')")
    public CommonResult<Boolean> deleteProductWarehouse(@RequestParam("id") Long id) {
        productWarehouseService.deleteProductWarehouse(id);
        return success(true);
    }

    @GetMapping("/get")
    @Operation(summary = "获得产品仓储信息")
    @Parameter(name = "id", description = "编号", required = true, example = "1024")
    @PreAuthorize("@ss.hasPermission('base:product-warehouse:query')")
    public CommonResult<ProductWarehouseRespVO> getProductWarehouse(@RequestParam("id") Long id) {
        ProductWarehouseDO productWarehouse = productWarehouseService.getProductWarehouse(id);
        ProductWarehouseRespVO respVO = BeanUtils.toBean(productWarehouse, ProductWarehouseRespVO.class);
        if (ObjectUtil.isNotEmpty(respVO)) {
            // 获取产品信息
            ProductInfoDO productInfo = productInfoService.getProductInfo(respVO.getProductId());
            if (ObjectUtil.isNotEmpty(productInfo)) {
                respVO.setProductName(productInfo.getName());
            }
        }
        return success(respVO);
    }

    @GetMapping("/get/product")
    @Operation(summary = "获得产品仓储信息")
    @Parameter(name = "id", description = "编号", required = true, example = "1024")
    @PreAuthorize("@ss.hasPermission('base:product-warehouse:query')")
    public CommonResult<ProductWarehouseRespVO> getProductWarehouseByProduct(@RequestParam("id") Long id) {
        ProductWarehouseDO productWarehouse = productWarehouseService.getProductWarehouseByProduct(id);
        ProductWarehouseRespVO respVO = BeanUtils.toBean(productWarehouse, ProductWarehouseRespVO.class);
        if (ObjectUtil.isNotEmpty(respVO)) {
            // 获取产品信息
            ProductInfoDO productInfo = productInfoService.getProductInfo(respVO.getProductId());
            if (ObjectUtil.isNotEmpty(productInfo)) {
                respVO.setProductName(productInfo.getName());
            }
        }
        return success(respVO);
    }

    @GetMapping("/page")
    @Operation(summary = "获得产品仓储信息分页")
    @PreAuthorize("@ss.hasPermission('base:product-warehouse:query')")
    public CommonResult<PageResult<ProductWarehouseRespVO>> getProductWarehousePage(@Valid ProductWarehousePageReqVO pageReqVO) {
        PageResult<ProductWarehouseDO> pageResult = productWarehouseService.getProductWarehousePage(pageReqVO);
        PageResult<ProductWarehouseRespVO> respVOS = BeanUtils.toBean(pageResult, ProductWarehouseRespVO.class);
        if (CollectionUtil.isNotEmpty(respVOS.getList())) {
            // 获取产品信息
            Set<Long> productIds = CollectionUtils.convertSet(respVOS.getList(), ProductWarehouseRespVO::getProductId);
            List<ProductInfoDO> productInfoList = productInfoService.getProductInfo(productIds);
            Map<Long, ProductInfoDO> productInfoMap = CollectionUtils.convertMap(productInfoList, ProductInfoDO::getId);
            Map<Long, UnitDO> unitMap = new HashMap<>();
            // 获取单位信息
            if (CollectionUtil.isNotEmpty(productInfoList)) {
                Set<Long> unitIds = CollectionUtils.convertSet(productInfoList, ProductInfoDO::getUnitId);
                List<UnitDO> unitList = unitService.getUnitList(unitIds);
                unitMap.putAll(CollectionUtils.convertMap(unitList, UnitDO::getId));
            }
            // 获取默认仓库信息
            Set<Long> inWarehouseIds = CollectionUtils.convertSet(respVOS.getList(), ProductWarehouseRespVO::getInWarehouse);
            Set<Long> outWarehouseIds = CollectionUtils.convertSet(respVOS.getList(), ProductWarehouseRespVO::getOutWarehouse);
            inWarehouseIds.addAll(outWarehouseIds);
            List<WarehouseRespDTO> warehouseList = warehouseApi.getWarehouseList(inWarehouseIds);
            Map<Long, WarehouseRespDTO> warehouseMap = CollectionUtils.convertMap(warehouseList, WarehouseRespDTO::getId);
            // 获取库位信息
            Set<Long> inPositionIds = CollectionUtils.convertSet(respVOS.getList(), ProductWarehouseRespVO::getInPosition);
            Set<Long> outPositionIds = CollectionUtils.convertSet(respVOS.getList(), ProductWarehouseRespVO::getOutPosition);
            inPositionIds.addAll(outPositionIds);
            List<PositionRespDTO> positionList = warehouseApi.getPositionList(inPositionIds);
            Map<Long, PositionRespDTO> positionMap = CollectionUtils.convertMap(positionList, PositionRespDTO::getId);
            //组装数据
            respVOS.getList().forEach(item -> {
                ProductInfoDO productInfo = productInfoMap.get(item.getProductId());
                if (ObjectUtil.isNotEmpty(productInfo)) {
                    item.setProductName(productInfo.getName());
                    item.setProductCode(productInfo.getCode());
                    item.setProductSpec(productInfo.getSpec());
                    item.setUnitId(productInfo.getUnitId());
                    UnitDO unit = unitMap.get(productInfo.getUnitId());
                    if (ObjectUtil.isNotEmpty(unit)) {
                        item.setUnitName(unit.getName());
                    }
                }
                WarehouseRespDTO inWarehouse = warehouseMap.get(item.getInWarehouse());
                if (ObjectUtil.isNotEmpty(inWarehouse)) {
                    item.setInWarehouseName(inWarehouse.getName());
                }
                WarehouseRespDTO outWarehouse = warehouseMap.get(item.getOutWarehouse());
                if (ObjectUtil.isNotEmpty(outWarehouse)) {
                    item.setOutWarehouseName(outWarehouse.getName());
                }
                PositionRespDTO inPosition = positionMap.get(item.getInPosition());
                if (ObjectUtil.isNotEmpty(inPosition)) {
                    item.setInPositionName(inPosition.getName());
                }
                PositionRespDTO outPosition = positionMap.get(item.getOutPosition());
                if (ObjectUtil.isNotEmpty(outPosition)) {
                    item.setOutPositionName(outPosition.getName());
                }
            });
        }
        return success(respVOS);
    }

    @GetMapping("/export-excel")
    @Operation(summary = "导出产品仓储信息 Excel")
    @PreAuthorize("@ss.hasPermission('base:product-warehouse:export')")
    @OperateLog(type = EXPORT)
    public void exportProductWarehouseExcel(@Valid ProductWarehousePageReqVO pageReqVO,
              HttpServletResponse response) throws IOException {
        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
        List<ProductWarehouseDO> list = productWarehouseService.getProductWarehousePage(pageReqVO).getList();
        // 导出 Excel
        ExcelUtils.write(response, "产品仓储信息.xls", "数据", ProductWarehouseRespVO.class,
                        BeanUtils.toBean(list, ProductWarehouseRespVO.class));
    }

}